package com.cocotingo.snail.template.models;

import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

public abstract class AttributedNode extends IDNode {
	
	private final List<String> attributeNames;
	private final Map<String, Attribute> attributes;
	
	public AttributedNode() {
		attributeNames = new LinkedList<String>();
		attributes = new Hashtable<String, Attribute>(1, 0.75f);
	}
	
	public final void addAttribute(Attribute attr) {
		addAttribute(attr, attributeNames.size());
	}
	
	public void addAttribute(Attribute attr, int index) {
		if (attributes.containsKey(attr.getName())) {
			throw new IllegalArgumentException("duplicate attribute name: " + attr.getName());
		}
		attributeNames.add(index, attr.getName());
		attributes.put(attr.getName(), attr);
	}
	
	public final boolean hasAttribute(String name) {
		return attributes.containsKey(name);
	}
	
	public final Attribute getAttribute(String name) {
		return attributes.get(name);
	}
	
	public void removeAttribute(String name) {
		if (attributes.containsKey(name)) {
			throw new IllegalArgumentException("can't find attribute with name:" + name);
		}
		attributeNames.remove(name);
		attributes.remove(name);
	}
	
	public Iterable<Attribute> attributes() {
		return new Iterable<Attribute>() {
			@Override
			public Iterator<Attribute> iterator() {
				final Iterator<String> it = attributeNames.iterator();
				return new Iterator<Attribute>() {

					@Override
					public boolean hasNext() {
						return it.hasNext();
					}

					@Override
					public Attribute next() {
						String name = it.next();
						return attributes.get(name);
					}

					@Override
					public void remove() {
						throw new UnsupportedOperationException();
					}
					
				};
			}
		};
	}
	
	public int attributeCount() {
		return attributeNames.size();
	}

}
